/**
 * \* Created with IntelliJ IDEA.
 * \* User: 冯若航
 * \* Date: 2021/6/21
 * \* Time: 18:36
 * \* To change this template use File | Settings | File Templates.
 * \* Description:
 * \
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 所谓interface，就是比抽象类还要抽象的纯抽象接口，因为它连字段都不能有。
 * 因为接口定义的所有方法默认都是public abstract的，所以这两个修饰符不需要写出来（写不写效果都一样）。
 *
 * 当一个具体的class去实现一个interface时，需要使用implements关键字。
 * 在Java中，一个类只能继承自另一个类，不能从多个类继承。但是，一个类可以实现多个interface
 */

public class 接口 {
    interface Hello{
        void hello();
    }

    /**
     * 一个interface可以继承自另一个interface
     * 此时，Person接口继承自Hello接口，因此，Person接口现在实际上有3个抽象方法签名，其中一个来自继承的Hello接口。
     */
    interface Person extends Hello{
        /**
         * 在接口中，可以定义default方法,例如，把Person接口的run()方法改为default方法
         * 实现类可以不必覆写default方法。default方法的目的是，当我们需要给接口新增一个方法时，
         * 会涉及到修改全部子类。如果新增的是default方法，那么子类就不必全部修改，只需要在需要覆写的地方去覆写新增方法。
         * default方法和抽象类的普通方法是有所不同的。因为interface没有字段，default方法无法访问字段，而抽象类的普通方法可以访问实例字段。
         */
        default void run(){
            System.out.println(getName() + " run");
        }
        String getName();
    }
    class Student implements Person{
        private String name;
        public Student(String name) {
            this.name = name;
        }
        @Override
        public void hello(){

        }

        @Override
        public String getName() {
            return name;
        }
    }

    //在使用的时候，实例化的对象永远只能是某个具体的子类，但总是通过接口去引用它，因为接口比抽象类更抽象：

    List list = new ArrayList();
    // 用List接口引用具体子类的实例
    Collection coll = list;
    // 向上转型为Collection接口
    Iterable it = coll;
    // 向上转型为Iterable接口

//    接口的静态字段
//    因为interface是一个纯抽象类，所以它不能定义实例字段。但是，interface是可以有静态字段的，并且静态字段必须为final类型：
//
//    public interface Person {
//        public static final int MALE = 1;
//        public static final int FEMALE = 2;
//    }
//    实际上，因为interface的字段只能是public static final类型，所以我们可以把这些修饰符都去掉，上述代码可以简写为：
//
//    public interface Person {
//        // 编译器会自动加上public statc final:
//        int MALE = 1;
//        int FEMALE = 2;
//    }
//    编译器会自动把该字段变为public static final类型。
}


